library DeltaChaingun initializer init requires LegacySystem

    globals
        private trigger AssemblyTrigger
        private trigger OperateTrigger
        private trigger StopTrigger
        private trigger DisassemblyTrigger
		private trigger FeedTrigger
		private trigger AttackTrigger
		private	unit                    udg_M242Chaingun           = null
				
		private	real                    udg_M242Rounds             = 0
		private rect                    udg_M242Area               = null
		
		private boolean                 udg_M242Active             = false
		private unit                    udg_M242Operator           = null
		private integer udg_ChaingunBuilt = 0
    endglobals
	

	function IsUnitChaingunOperator takes unit u returns boolean
		return u == udg_M242Operator
	endfunction
	
	private function SetChaingunCommandsEnabled takes boolean b returns nothing
        if b then
            call EnableTrigger(OperateTrigger)
            call EnableTrigger(StopTrigger)
			call EnableTrigger(FeedTrigger)
            call EnableTrigger(AttackTrigger)
			call EnableTrigger(DisassemblyTrigger)
        else
            call DisableTrigger(OperateTrigger)
            call DisableTrigger(StopTrigger)
	        call DisableTrigger(FeedTrigger)
            call DisableTrigger(AttackTrigger)
			call DisableTrigger(DisassemblyTrigger)
        endif
    endfunction
	
    private function IsAttackerTheChaingun takes nothing returns boolean
        return GetAttacker() == udg_M242Chaingun
    endfunction
	
	private function IsTriggerUnitTheChaingun takes nothing returns boolean
        return GetTriggerUnit() == udg_M242Chaingun
    endfunction
	
    private function M242AmmunitionFeed2 takes nothing returns nothing
        local item i = GetManipulatedItem()
        local unit u = GetTriggerUnit()
        local integer id = GetItemTypeId(i)
        if id=='I006' or id=='shas' then
            call PauseUnit(u,false)
            call MachineGunLink(u)
            call SetUnitState(u,UNIT_STATE_MANA,GetUnitState(u,UNIT_STATE_MANA)+(50*I2R(GetItemCharges(i))))
            call AddFadingTextTag("+"+I2S(50*GetItemCharges(i)),GetUnitX(u),GetUnitY(u),255,220,0,200)
            call RemoveItem(i)
        else
            call UnitRemoveItem(u,i)
        endif
        set i = null
        set u = null
    endfunction


    private function M242AmmunitionSystem2 takes nothing returns nothing
        local unit u = GetAttacker()
        local real rounds = GetUnitState(u,UNIT_STATE_MANA)
        if rounds<0.5 then
            call IssueImmediateOrder(u,"stop")
        elseif GetUnitTypeId(u)=='h00D' and (udg_M242Operator == null or GetWidgetLife(udg_M242Operator)< 0.405 or udg_M242Active==false) then
            call PauseUnit(u,true)
        else
            if rounds-1.0<0 then
                set rounds=0
            else
                set rounds=rounds-1.0
            endif
            call SetUnitState(u,UNIT_STATE_MANA,rounds)
        endif
        set u = null
    endfunction
	

    private function M242Disassembly takes nothing returns nothing
        local real x = GetUnitX(udg_M242Chaingun)
        local real y = GetUnitY(udg_M242Chaingun)
        local player p
        local integer i
        if udg_M242Operator!=null then
            set p = GetOwningPlayer(udg_M242Operator)
            set i = GetConvertedPlayerId(p)
            call UnitRemoveAbility(udg_M242Operator,'A03L')
        endif
        if GetSpellAbilityId()=='A053' then
            if GetUnitState(udg_M242Chaingun,UNIT_STATE_MANA)<2 then
                set udg_M242Rounds = 0.0
            else
                set udg_M242Rounds = GetUnitState(udg_M242Chaingun,UNIT_STATE_MANA)
            endif
            call CreateItem('I00Q',x,y)
            call CreateItem('I00R',x,y)
            call CreateItem('I00P',x,y)
            call KillUnit(udg_M242Chaingun)
            call DisplayTimedTextToPlayer( GetLocalPlayer(), 0.0, 0.0, 10.0, "M242 disassembled." )
            if udg_M242Operator!=null and udg_M242Operator==udg_Hero[i] and GetPrimaryAmmoRounds(p)==0 and (GetPrimaryAmmoMagazines(p)==0 or GetUnitTypeId(udg_Hero[i])=='H000') then
                set udg_Reloading[i]=3
            elseif udg_M242Operator==udg_Hero[i] then
                set udg_Reloading[i]=0
            elseif udg_M242Operator!=null then
                call SetLoadState(I2S(GetHandleId(udg_M242Operator)),1)
            endif
            set udg_M242Active = false
            set udg_M242Operator = null
            call EnableTrigger(AssemblyTrigger)
        endif
    endfunction

    private function M242StopConditions takes nothing returns boolean
        return GetTriggerUnit()==udg_M242Operator and GetWidgetLife(udg_M242Chaingun)>0.405
    endfunction

    private function M242Stop takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local player p = GetOwningPlayer(u)
        local integer i = GetConvertedPlayerId(p)
        local integer adjust = 0
        if udg_M242Operator==udg_Hero[i] then
            set adjust = 1
        endif
        call UnitRemoveAbility(udg_M242Operator,'A03L')
        if GetWidgetLife(udg_M242Chaingun)<0.405 then
            call SetChaingunCommandsEnabled(false)
        else
            call PauseUnit(udg_M242Chaingun,true)
        endif
        if adjust==1 and GetPrimaryAmmoRounds(p)==0 and (GetPrimaryAmmoMagazines(p)==0 or GetUnitTypeId(udg_Hero[i])=='H000') then
            set udg_Reloading[i]=3
        elseif adjust==1 then
            set udg_Reloading[i]=0
        else
            call SetLoadState(I2S(GetHandleId(u)),1)
        endif
        set bj_meleeNearestMineDist = GetUnitX(u)
        set bj_lastTransmissionDuration = GetUnitY(u)
        set udg_soundpath = "war3mapImported\\Reload.mp3"
        call PlaySoundPath3D.execute()
        set udg_M242Operator = null
        set udg_M242Active = false
        set u = null
    endfunction

    private function M242OperateConditions takes nothing returns boolean
        local integer i = GetUnitPointValue(GetTriggerUnit())
        local real dx = GetUnitX(GetTriggerUnit()) - GetUnitX(udg_M242Chaingun)
        local real dy = GetUnitY(GetTriggerUnit()) - GetUnitY(udg_M242Chaingun)
        return GetWidgetLife(udg_M242Operator)<=0.405 and GetWidgetLife(udg_M242Chaingun)>0.405 and (i==10 or i==12) and GetUnitTypeId(GetTriggerUnit())!='h00E' and dx*dx+dy*dy<=360000.0
    endfunction

    private function M242Operate takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local player p = GetOwningPlayer(u)
        local integer i = GetConvertedPlayerId(p)
        set bj_meleeNearestMineDist = GetUnitX(u)
        set bj_lastTransmissionDuration = GetUnitY(u)
        set udg_soundpath = "war3mapImported\\AmmoLink.mp3"
        call PlaySoundPath3D.execute()
        set udg_M242Operator = GetTriggerUnit()
        call UnitAddAbility(udg_M242Operator,'A03L')
        call PauseUnit(udg_M242Chaingun,false)
        set udg_M242Active = true
        if udg_M242Operator==udg_Hero[i] then
            set udg_Reloading[i] = 4
        else
            call SetLoadState(I2S(GetHandleId(u)),2)
        endif
        set u = null
    endfunction

    private function M242AssemblyConditions takes nothing returns boolean
        local integer i = GetItemTypeId(GetManipulatedItem())
        return i=='I00Q' or i=='I00R' or i=='I00P' or i=='I00S'
    endfunction

    private function M242Assembly takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local real x = GetUnitX(u)
        local real y = GetUnitY(u)
        local rect r
        local player p = GetOwningPlayer(u)
        local integer i = GetConvertedPlayerId(p)
        local integer A = 1
        if GetUnitItem(u,'I00Q')!=null and GetUnitItem(u,'I00R')!=null and GetUnitItem(u,'I00P')!=null and (GetUnitTypeId(u)=='H007' or GetUnitTypeId(u)=='z004' or GetUnitItem(u,'I00S')!=null) then
            call DisableTrigger(GetTriggeringTrigger())
            loop
                exitwhen A>3
                call RemoveItem(GetUnitItem(u,udg_M242Components[A]))
                set A=A+1
            endloop
            set udg_M242Chaingun = CreateUnit(p,'h00D',x,y,0.0)
            call SetUnitState(udg_M242Chaingun, UNIT_STATE_MANA, udg_M242Rounds)
            call SetChaingunCommandsEnabled(true)
            set r = Rect(x-200,y-200,x+200,y+200)
            // leak here but whatever
            call TriggerRegisterEnterRectSimple(OperateTrigger,r)
            call TriggerRegisterLeaveRectSimple(StopTrigger,r)

            call ALICEText(10.0, "|cfff3ad00ALICE|r : M242 assembled." )
            set udg_M242Operator = GetTriggerUnit()
            set udg_M242Active = true
            if udg_M242Operator==udg_Hero[i] then
                set udg_Reloading[i] = 4
            else
                call SetLoadState(I2S(GetHandleId(u)),2)
            endif
            set udg_ChaingunBuilt = udg_ChaingunBuilt + 1
            call UnitAddAbility(udg_M242Operator,'A03L')
            if udg_ChaingunBuilt==1 and udg_Mode==1 then
                set i = 1
                call ALICE2Text(10.0, "M242 Chaingun successfully assembled. |cff1e90ff60 XP|r awarded to all Marines." )
                loop
                    exitwhen i>udg_InitialPlayers
                    if GetPlayerSlotState(ConvertedPlayer(udg_Sorted[i]))!=PLAYER_SLOT_STATE_LEFT then
                        set udg_Experience[udg_Sorted[i]] = udg_Experience[udg_Sorted[i]] + 60
                    endif
                    set i=i+1
                endloop
            endif
        endif
    endfunction

    private function init takes nothing returns nothing
        local trigger t
        
        set AssemblyTrigger = CreateTrigger()
		call TriggerRegisterAnyUnitEventBJ( AssemblyTrigger, EVENT_PLAYER_UNIT_PICKUP_ITEM )
        call TriggerAddCondition( AssemblyTrigger, Condition( function M242AssemblyConditions ) )
        call TriggerAddAction( AssemblyTrigger, function M242Assembly )
      
        
        set DisassemblyTrigger = CreateTrigger()
        call TriggerAddAction( DisassemblyTrigger, function M242Disassembly )
        call TriggerAddCondition( DisassemblyTrigger, Condition( function IsTriggerUnitTheChaingun ) )
        call TriggerRegisterAnyUnitEventBJ(DisassemblyTrigger, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call DisableTrigger(DisassemblyTrigger)
        
        set OperateTrigger = CreateTrigger()
        call TriggerAddCondition(OperateTrigger,Condition(function M242OperateConditions))
        call TriggerAddAction(OperateTrigger,function M242Operate)
        call DisableTrigger(OperateTrigger)
        
        set StopTrigger = CreateTrigger()
        call TriggerAddCondition( StopTrigger, Condition( function M242StopConditions ) )
        call TriggerAddAction( StopTrigger, function M242Stop )
        call DisableTrigger(StopTrigger)
  
		set FeedTrigger = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( FeedTrigger, EVENT_PLAYER_UNIT_PICKUP_ITEM )
        call TriggerAddCondition( FeedTrigger, Condition( function IsTriggerUnitTheChaingun ) )
        call TriggerAddAction( FeedTrigger, function M242AmmunitionFeed2 )
		call DisableTrigger(OperateTrigger)

        set AttackTrigger = CreateTrigger()
        call TriggerRegisterPlayerUnitEvent(AttackTrigger, Player(13), EVENT_PLAYER_UNIT_ATTACKED, null)
        call TriggerRegisterPlayerUnitEvent(AttackTrigger, Player(14), EVENT_PLAYER_UNIT_ATTACKED, null)
        call TriggerRegisterPlayerUnitEvent(AttackTrigger, Player(9), EVENT_PLAYER_UNIT_ATTACKED, null)
        call TriggerAddCondition( AttackTrigger, Condition( function IsAttackerTheChaingun ) )
        call TriggerAddAction( AttackTrigger, function M242AmmunitionSystem2 )
		call DisableTrigger(AttackTrigger)
		
		set udg_M242Rounds = 150.00
		set udg_M242Area = null
		set udg_M242Active = false
		set udg_M242Operator = null
    endfunction

endlibrary